package com.taokatao.cardmee;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.taokatao.cardmee.api.ApiManager;
import com.taokatao.cardmee.api.RespWrapper;
import com.taokatao.cardmee.api.SubscriberAdapter;
import com.taokatao.cardmee.api.model.CardShareInfo;
import com.taokatao.cardmee.api.security.ServiceUrlProvider;
import com.taokatao.cardmee.common.widget.AlertDialog;
import com.taokatao.cardmee.common.widget.AlertEditDialog;
import com.taokatao.cardmee.common.widget.ProgressLineView;
import com.taokatao.cardmee.common.widget.ShareDialog;
import com.umeng.socialize.ShareAction;
import com.umeng.socialize.UMShareListener;
import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.media.UMImage;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import com.taokatao.cardmee.R;

@SuppressLint({"JavascriptInterface", "SetJavaScriptEnabled"})
public class WebLayout extends FrameLayout implements View.OnClickListener {
    @BindView(R.id.l_error) View lError;
    @BindView(R.id.t_error) TextView tError;
    @BindView(R.id.v_web) public WebView webView;
    @BindView(R.id.v_progress) ProgressLineView vProgress;

    private boolean isOpenNewPage = false;
    private Callback callback;

    private ShareDialog dlgShare;

    public WebLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        ButterKnife.bind(this, LayoutInflater.from(context).inflate(R.layout.layout_web, this));
    }

    public void setCallback(Callback cb) {
        callback = cb;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        if (!isInEditMode()) {
            // 设置 缓存模式
            webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
            // 开启 DOM storage API 功能
            webView.getSettings().setDomStorageEnabled(true);
            // 开启 database storage API 功能
            webView.getSettings().setDatabaseEnabled(true);
            webView.getSettings().setAppCacheEnabled(true);
            // 设置可以支持缩放
            webView.getSettings().setSupportZoom(true);
            // 设置出现缩放工具
            webView.getSettings().setBuiltInZoomControls(true);
            webView.getSettings().setDisplayZoomControls(false);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setLoadWithOverviewMode(true);
            // 扩大比例的缩放
            webView.getSettings().setUseWideViewPort(true);
            // 自适应屏幕
            webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
            webView.getSettings().setLoadWithOverviewMode(true);

            webView.addJavascriptInterface(new JSInterface(), "cardMee_android");
            // webView.loadData("", "text/html", null);
            webView.setWebViewClient(viewClient);
            webView.setWebChromeClient(chromeClient);
        }
    }

    public void loadUrl(String url) {
        webView.loadUrl(url);
    }

    @Override
    @OnClick({R.id.t_error})
    public void onClick(View v) {
        if (v == tError) {
            lError.setVisibility(View.GONE);
            webView.reload();
        }
    }

    public void setOpenNewPage(boolean openNewPage) {
        isOpenNewPage = openNewPage;
    }

    class JSInterface {
        @JavascriptInterface
        public void cardMeeAppExec(final String cmd) {
            Utils.logd("JSInterface cardMeeAppExec message %s", cmd);
            post(new Runnable() {
                @Override
                public void run() {
                    if (callback != null)callback.onAppExec(cmd);
                }
            });
        }

        @JavascriptInterface
        public void cardMeeTestMessage(final String message) {
            Utils.logd("JSInterface cardMeeTestMessage message %s", message);
            post(new Runnable() {
                @Override
                public void run() {
                    Utils.showToast(message);
                }
            });
        }


        @JavascriptInterface
        public void cardMeeAddImageMenu(final String action) {
            Utils.logd("JSInterface cardMeeAddImageMenu action %s", action);
            post(new Runnable() {
                @Override
                public void run() {
                    if (callback != null) callback.onMenuAction("image", action);
                }
            });
        }

        @JavascriptInterface
        public void cardMeeAddTextMenu(final String action) {
            Utils.logd("JSInterface cardMeeAddTextMenu action %s", action);
            post(new Runnable() {
                @Override
                public void run() {
                    if (callback != null) callback.onMenuAction("text", action);
                }
            });
        }

        @JavascriptInterface
        public void cardMeeShareMyMemberCard(long mCardID, String mCardName, String cardPicUrl) {
            Utils.logd("JSInterface cardMeeShareMyMemberCard cardID:" + mCardID + " #cardName:" + mCardName + " #cardPicUrl:" + cardPicUrl);
            showShareDialog(mCardID, mCardName, cardPicUrl);
        }

        @JavascriptInterface
        public String cardMeeContainsApplication() {
            Utils.logd("JSInterface cardMeeContainsApplication");
            return "alipay#wechat";
        }

        @JavascriptInterface
        public void cardMeeOpenApplication(String platform) {
            Utils.logd("JSInterface cardMeeOpenApplication platform:" + platform);
            if (TextUtils.equals(platform, "alipay")) {
                try {
                    Intent intent = new Intent();
                    intent.setComponent(new ComponentName("com.eg.android.AlipayGphone", "com.eg.android.AlipayGphone.AlipayLogin"));
                    intent.setAction(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getContext().startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                    Utils.showToast("支付宝客户端打开失败");
                }
            } else if (TextUtils.equals(platform, "wechat")) {
                try {
                    Intent intent = new Intent();
                    intent.setComponent(new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"));
                    intent.setAction(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_LAUNCHER);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getContext().startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                    Utils.showToast("微信客户端打开失败");
                }
            }
        }

        @JavascriptInterface
        public void cardMeeCancelCollectionMyMemberCard(long mCardId, String type) {
            Utils.logd("JSInterface cardMeeCancelCollectionMyMemberCard cardId:" + mCardId + " #type:" + type);
            // 0收藏完成  1取消收藏
            if (TextUtils.equals("0", type)) {
                Utils.postMainThreadBusEvent(BusEvent.CARD_REFRESH);
            } else if (TextUtils.equals("1", type)) {
                Utils.postMainThreadBusEvent(BusEvent.CARD_REFRESH);
            }
        }
    }

    private void showShareDialog(final long mCardID, final String mCardName, final String cardPicUrl) {
        if (dlgShare == null) {
            dlgShare = new ShareDialog.Builder(getContext()).setCallback(new ShareDialog.OnShareClickListener() {
                @Override
                public void onPlatformClick(Dialog dialog, SHARE_MEDIA platform) {
                    requestObtainCardShareUrl(platform, mCardID, mCardName, cardPicUrl);
                    dialog.dismiss();
                }
            }).create();
        }
        dlgShare.show();
    }

    private void requestObtainCardShareUrl(final SHARE_MEDIA platform, final long mCardID, final String mCardName, final String cardPicUrl) {
        ApiManager.i().obtainCardShareUrl(getContext(), App.i().getCurrUser().getUuid(), mCardID, new SubscriberAdapter<RespWrapper<CardShareInfo>>() {
            @Override
            public void onNext(RespWrapper<CardShareInfo> o) {
                super.onNext(o);
                if (o.code == C.http.RESULT_CODE_SUCCESS) {
                    UMImage image = new UMImage(getContext(), cardPicUrl);
                    String mName = "我";
                    if (App.i().getCurrUser() != null && !TextUtils.isEmpty(App.i().getCurrUser().getUserName())) {
                        mName = App.i().getCurrUser().getUserName();
                    }
                    String mShareTitle = mName + "分享的" + mCardName;
                    new ShareAction((Activity) getContext()).setPlatform(platform)
                            .withText("不准外传！\n ▍▎▏▏▎▏▏▎▍")
                            .withTitle(mShareTitle)
                            .withTargetUrl(o.decode(CardShareInfo.class).shareMcardUrl)
                            .withMedia(image)
                            .setCallback(new UMShareListener() {
                                @Override
                                public void onResult(SHARE_MEDIA share_media) {
                                    webView.loadUrl("javascript:responseCallback(\"success\")");
                                    Utils.showToast("分享成功");
                                }

                                @Override
                                public void onError(SHARE_MEDIA share_media, Throwable throwable) {
                                    Utils.showToast("分享失敗");
                                }

                                @Override
                                public void onCancel(SHARE_MEDIA share_media) {
                                    Utils.showToast("分享取消");
                                }
                            }).share();
                }
            }
        }.showProgress(getContext()));
    }

    private WebChromeClient chromeClient = new WebChromeClient() {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            vProgress.setVisibility(newProgress < 100 ? View.VISIBLE : View.GONE);
            vProgress.updateProgress(newProgress);
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            try {
                final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());

                builder.setTitle("对话框").setMessage(message).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                // 禁止响应按back键的事件
                builder.setCancelable(false);
                AlertDialog dialog = builder.create();
                dialog.show();
                result.confirm();// 因为没有绑定事件，需要强行confirm,否则页面会变黑显示不了内容。
            } catch (Exception e) {
                e.printStackTrace();
                Utils.loge("wap on js alert : activity die ? ~");
            }
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
            try {
                final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
                builder.setTitle("对话框").setMessage(message).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        result.confirm();
                        dialog.dismiss();
                    }
                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        result.cancel();
                        dialog.dismiss();
                    }
                });
                // 禁止响应按back键的事件
                builder.setCancelable(false);
                AlertDialog dialog = builder.create();
                dialog.show();
            } catch (Exception e) {
                e.printStackTrace();
                Utils.loge("wap on js alert : activity die ? ~");
            }
            return true;
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
            try {
                final AlertEditDialog.Builder builder = new AlertEditDialog.Builder(view.getContext());
                builder.setTitle(message);
                builder.setCallback(new AlertEditDialog.Callback() {
                    @Override
                    public void onCompleted(AlertEditDialog dialog, String inputContent) {
                        result.confirm(inputContent);
                    }

                    @Override
                    public void onCancel(AlertEditDialog dialog) {
                        result.cancel();
                    }
                });
                builder.create().show();
            } catch (Exception e) {
                e.printStackTrace();
                Utils.loge("wap on js alert : activity die ? ~");
            }
            return true;
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
        }
    };

    private WebViewClient viewClient = new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            Utils.logd("WebViewClient onReceivedError title[%s]", webView.getTitle());
            lError.setVisibility(View.VISIBLE);
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Utils.logd("WebViewClient shouldOverrideUrlLoading[canGoback %b] url %s", view.canGoBack(), url);
            if (isOpenNewPage && !ServiceUrlProvider.isMoreRootUrl(url)) {
                Intent intent = new Intent(getContext(), WebActivity.class);
                intent.putExtra("extra_url", url);
                intent.putExtra("extra_is_support_close", false);
                getContext().startActivity(intent);
            } else {
                view.loadUrl(url);
            }

            if (callback != null) callback.onMenuAction("clear", "");
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            Utils.logd("WebViewClient onPageStarted canGoBack[%b] title[%s] url[%s]", webView.canGoBack(), webView.getTitle(), url);
            if (callback != null) {
                callback.onPageStarted(!webView.canGoBack());
            }
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Utils.logd("WebViewClient onPageFinished title[%s] url[%s]", webView.getTitle(), url);

            if (callback != null) {
                callback.onPageFinished(!webView.canGoBack());
            }
        }
    };

    public interface Callback {
        void onPageStarted(boolean isRootPage);

        void onPageFinished(boolean isRootPage);

        // menuAction
        void onMenuAction(String type, String menuAction);

        void onAppExec(String cmd);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // Check if the key event was the Back button and if there's history
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            if (webGoBack())
                return true;
        }
        // If it wasn't the Back key or there's no web page history, bubble up
        // to the default
        // system behavior (probably exit the activity)
        return super.onKeyDown(keyCode, event);
    }

    public boolean webGoBack() {
        if (webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        return false;
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (isInEditMode()) return;
        if (webView != null) {
            webView.onResume();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (webView != null) {
            webView.onPause();
        }
    }

}
